#!/usr/bin/env python
import sys
from os.path import isfile

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import numpy as N
import scipy as S
#import pylab as P

from ui_Plot_Widget import Ui_Plot_Widget
from Plot_Options_Line2D import Plot_Options_Dialog
from Remove_Line_Dialog import Remove_Line_Dialog

from plot_scripting import probeLPC

from plotDataClass import LPC

from matplotlib.lines import Line2D
from matplotlib.widgets import SpanSelector
from pylab import errorbar

import shell
from Python_Highlighter import TextEdit, PythonHighlighter
from code import InteractiveInterpreter as Interpreter

line_colors = ['#0000ff','#ff0000','#55aa00','#ffaa00','#ff55ff','#ff55ff',
                '#000000','#aa5500', '#aa55ff', '#ffff00']

def isAlive(qobj):#new
    import sip
    try:
        sip.unwrapinstance(qobj)
    except RuntimeError:
        return False
    return True

class Plot_Widget(QWidget):
    NextId = 1
    
    Instances = set()
    '''data2plot LinePlotClass instance.  It does not require an x array to
    plot and multiple y arrays may be held in a single instance.  
    '''
    def __init__(self, data2plot=None, parent = None,  varDict = None):
        super(Plot_Widget, self).__init__(None)#new  new^2:changed from parent
        self.setAttribute(Qt.WA_DeleteOnClose)#new
        Plot_Widget.Instances.add(self)#new
        
        self.ui = Ui_Plot_Widget()
        self.ui.setupUi(self)
        self.parent = None
        self.varDict = {}
        if varDict:
            self.varDict = varDict
        if parent:
            self.parent = parent
            self.varDict = parent.localVars.getPubDict()
            #print parent.dialog_test
            parent.topPlot = self.ui
            #print parent.localVars.getPubDict().keys()
        self.windowTitle = "Plot%d" % Plot_Widget.NextId
        self.setWindowTitle(self.windowTitle)
        Plot_Widget.NextId +=1
        self.plotTitle = "Subplot"
        self.xtitle = "x-axis"
        self.ytitle = "y-axis"
        self.grids = False #this is used because I can't find the pylab bool status for the grids
        self.logx = False
        self.logy = False
        self.xscale = None
        self.yscale = None
        self.plotDict = {}#will contain all of the y values in the plot
        self.errorDict = {}#will contain references to the error bars if added
        self.lpcDict = {}#it would nice to merge this with the plotDict but I didn't need to until now--a bit ugly
        self.plotscript = None
        self.plotParams = None
        self.line_num = 0
        self.lineId = 1
        
        if data2plot:
            self.initialize_plot(data2plot)
        
        
        #self.ui.mpl_widget.canvas.mpl_connect('draw_event', self.ondraw) 
        
        self.is_hZoom = False
        # set useblit True on gtkagg for enhanced performance
        self.span = SpanSelector(self.ui.mpl_widget.canvas.ax, self.onselect, 'horizontal', 
                                 useblit=True, rectprops=dict(alpha=0.5, facecolor='#C6DEFF') )#There is a bug in mpl 0.91 'blue' is red and 'red' is blue
        #print self.span            
        self.span.visible = False
        
        self.xlist = {}#used just for reference
        
        self.dx = None
        self.dy = None
        self.cursorAInfo=[0, 0, 0, 0]
        self.cursorBInfo=[0, 0, 0, 0]
        self._cidPlotA = None#used for picker
        self._cidPlotB = None#used for picker
        self.mplPickPointsA = False#originally was False#also used for picker
        self.mplPickPointsB = False
        self.indexA = 0
        self.indexB = 0
        self.selectHandleA,  = self.ui.mpl_widget.canvas.ax.plot([0], [0], 'o',\
                                        ms=8, alpha=.4, color='yellow', visible=False,  label = 'Cursor A')
        self.selectHandleB,  = self.ui.mpl_widget.canvas.ax.plot([0], [0], 's',\
                                        ms=8, alpha=.4, color='green', visible=False,  label = 'Cursor B')
        
        self.ui.handleActionA = QAction("Cursor A", self)
        self.ui.mpl_widget.addAction(self.ui.handleActionA)
        
        self.ui.handleActionB = QAction("Cursor B", self)
        self.ui.mpl_widget.addAction(self.ui.handleActionB)
        
        self.ui.cursorClear = QAction("Clear Cursors",  self)
        self.ui.mpl_widget.addAction(self.ui.cursorClear)
        
        self.ui.appendAction = QAction("Add Trace",  self)
        self.ui.mpl_widget.addAction(self.ui.appendAction)
       
        self.ui.removeAction = QAction("Remove Trace",  self)
        self.ui.mpl_widget.addAction(self.ui.removeAction)
        
        self.ui.fitAction = QAction("Fit Function",  self)
        self.ui.mpl_widget.addAction(self.ui.fitAction)
 
        self.ui.saveGraphAction = QAction("Save Graph",  self)
        self.ui.mpl_widget.addAction(self.ui.saveGraphAction) 
        
        self.ui.errorbarAction = QAction("Error Bars",  self)
        self.ui.mpl_widget.addAction(self.ui.errorbarAction)
        
        self.ui.testAction = QAction("Test Function",  self)
        self.ui.mpl_widget.addAction(self.ui.testAction)
        
        self.ui.hZoom = QAction("Horizontal Zoom",  self)
        self.ui.hZoom.setShortcut("Ctrl+Shift+Z")
        self.ui.mpl_widget.addAction(self.ui.hZoom)
        
        self.ui.mpl_widget.addAction(self.ui.actionAutoScale)
        self.ui.mpl_widget.addAction(self.ui.actionZoom)
        self.ui.mpl_widget.addAction(self.ui.actionClear)
        self.ui.mpl_widget.addAction(self.ui.actionPlotOptions)

        
        self.connect(self.ui.btn_TestPlot, SIGNAL("clicked()"),
                     self.test_plot)
        self.connect(self.ui.btn_AutoScale, SIGNAL("clicked()"),
                     self.autoscale_plot)
        self.connect(self.ui.btn_Clear, SIGNAL("clicked()"),
                     self.clear_plot)
        self.connect(self.ui.btn_PlotOptions, SIGNAL("clicked()"),
                     self.plot_option_dialog)
        self.connect(self.ui.actionPlotOptions,SIGNAL("triggered()"),
                     self.plot_option_dialog)
        self.connect(self.ui.actionAutoScale,SIGNAL("triggered()"),
                     self.autoscale_plot)
        self.connect(self.ui.actionClear,SIGNAL("triggered()"),
                     self.clear_plot)
        self.connect(self.ui.actionZoom,SIGNAL("triggered()"),
                     self.zoom_plot)
        self.connect(self.ui.handleActionA,SIGNAL("triggered()"),
                     self.SelectPointsA)
        self.connect(self.ui.handleActionB,SIGNAL("triggered()"),
                     self.SelectPointsB)
        self.connect(self.ui.cursorClear,SIGNAL("triggered()"),
                     self.cursorClear)
        
        self.connect(self.ui.appendAction,SIGNAL("triggered()"),
                     self.appendTrace)
        self.connect(self.ui.removeAction,SIGNAL("triggered()"),
                     self.removeTrace)
        
        self.connect(self.ui.errorbarAction, SIGNAL("triggered()"), 
                     self.appendErrorBars)
        
        self.connect(self.ui.fitAction,SIGNAL("triggered()"),
                     self.fitData)
        self.connect(self.ui.saveGraphAction,SIGNAL("triggered()"),
                     self.getPlotScript)
        
        self.connect(self.ui.testAction,SIGNAL("triggered()"),
                     self.testScript)
        
        self.connect(self.ui.hZoom,SIGNAL("triggered()"),
                     self.hZoomToggle)
        
        self.connect(self, SIGNAL("destroyed(QObject*)"),
                     Plot_Widget.updateInstances)
        
        
        self.__initContextMenus__()
        self.__initLocalVars__()
        self.__addWidgets__()
    
    def hZoomToggle(self):
        if self.is_hZoom:
            self.is_hZoom = False
            self.span.visible = False
        else:
            self.is_hZoom = True
            self.span.visible = True
    
    def onselect(self,  xmin, xmax):
            if self.is_hZoom:
                self.ui.mpl_widget.canvas.ax.set_xlim(xmin,  xmax)
                self.ui.mpl_widget.canvas.draw()


    
    def ondraw(self, event):
        print "draw"

    def testScript(self):
        if type(self.cursorAInfo[3]) == str and type(self.cursorBInfo[3]) == str:
            if self.cursorAInfo[3] == self.cursorBInfo[3]:
                print 'A', self.selectHandleA.get_xdata(),  self.selectHandleA.get_ydata(),  self.indexA
                print 'B', self.selectHandleB.get_xdata(),  self.selectHandleB.get_ydata(),  self.indexB
                subdata = self.plotDict.get(self.cursorAInfo[3])
                self.ui.mpl_widget.canvas.ax.plot(subdata.get_xdata()[self.indexA:self.indexB], subdata.get_ydata()[self.indexA:self.indexB], 'ro')
                

##used to set a list to the shell
#        g = ['test = 1.2341',  'game = N.arange(0,10)']
#        for i in range(len(g)):
#            g[i] = unicode(g[i]+'\n')
#        print g
#        self.shell.setFocus()
#        return self.shell.fakeUser(g)
##used to get shell history into a list        
#        self.shell.history = g
#        print self.shell.history
#        for line in self.shell.history:
#            print str(line)
#            print type(str(line))
        print "Test Script"
    
    def refreshPlotScripts(self):
        for line in self.ui.mpl_widget.canvas.ax.get_lines():
            if self.plotDict.has_key(line.get_label()):
                pass
            elif line.get_label() == 'Cursor A' or line.get_label() == 'Cursor B':
                pass
            else:
                lineLabel = "line%d" % self.lineId
                line.set_label(lineLabel)
                self.plotDict[lineLabel] = line
                newLPC = LPC()
                newLPC.set_data(line)
                newLPC.ylabel = lineLabel
                self.lpcDict[lineLabel] = newLPC
                self.lineId += 1
    
    def __addWidgets__(self):
        '''adds all of the custom widgets not specified in the .ui file'''
        #interpreter = Interpreter(self.localVars.__dict__)#original
        interpreter = Interpreter(self.varDict)
        #interpreter = Interpreter()
        shellClass = shell.get_shell_class()
        
        self.shell = shellClass(interpreter,parent=self.ui.pyDockWidget)
        self.shell.setObjectName("shell")
        self.ui.pyDockWidget.setWidget(self.shell)
    
    def __initLocalVars__(self):
        '''Initialization of variables
        All of those variables specified below will be avialable to the user
        '''
        #self.localVars.setPubTypes(self.localVarTypes)
        self.varDict['__ghost__'] = []
        #self.localVars['P'] = P
        self.varDict['N'] = N
        self.varDict['S'] = S
        self.varDict['ax'] = self.ui.mpl_widget.canvas.ax
        #self.varDict['span'] = self.span
        self.varDict['canvas'] = self.ui.mpl_widget.canvas
        
    @staticmethod
    def updateInstances(qobj):
        Plot_Widget.Instances = set([window for window \
                in Plot_Widget.Instances if isAlive(window)])
                        
    def __initContextMenus__(self):
        self.ui.mpl_widget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.mpl_widget.connect(self.ui.mpl_widget, SIGNAL("customContextMenuRequested(QPoint)"), self.__mplContext__)
    
    def cursorClear(self):
        if self._cidPlotA:
            self.selectHandleA.set_visible(False)
            self.ui.mpl_widget.canvas.mpl_disconnect(self._cidPlotA)
            self._cidPlotA = None
            self.mplPickPointsA = False
            self.ui.lineEdit_R.setText('')
        
        if self._cidPlotB:
            self.selectHandleB.set_visible(False)
            self.ui.mpl_widget.canvas.mpl_disconnect(self._cidPlotB)
            self._cidPlotB = None
            self.mplPickPointsB = False
            self.ui.lineEdit_L.setText('')
        
        #print "cidA ", self._cidPlotA
        #print "cidB ", self._cidPlotB
        self.ui.mpl_widget.canvas.draw()
        
    def cursorStats(self):
        if self._cidPlotA and self._cidPlotB:
            self.dx = self.cursorAInfo[1]-self.cursorBInfo[1]
            self.dy = self.cursorAInfo[2]-self.cursorBInfo[2]
            cursorAText = 'point: %i\tx: %f\ty: %f\tdx: %f\t%s' % (self.cursorAInfo[0], self.cursorAInfo[1], self.cursorAInfo[2], self.dx, self.cursorAInfo[3])
            cursorBText = 'point: %i\tx: %f\ty: %f\tdy: %f\t%s' % (self.cursorBInfo[0], self.cursorBInfo[1], self.cursorBInfo[2],  self.dy,  self.cursorBInfo[3])
            self.ui.lineEdit_R.setText(cursorAText)
            self.ui.lineEdit_L.setText(cursorBText)
            return True
        if self._cidPlotA:
            cursorAText = 'point: %i\tx: %f\ty: %f\t%s' % (self.cursorAInfo[0], self.cursorAInfo[1], self.cursorAInfo[2], self.cursorAInfo[3])
            self.ui.lineEdit_R.setText(cursorAText)
        if self._cidPlotB:
            cursorBText = 'point: %i\tx: %f\ty: %f\t%s' % (self.cursorBInfo[0], self.cursorBInfo[1], self.cursorBInfo[2],  self.cursorBInfo[3])
            self.ui.lineEdit_L.setText(cursorBText)
            
    def SelectPointsA(self):
        """
        This method will be called from the plot context menu for 
        selecting points
        """
        #ico1 = QtGui.QIcon("graphics/tick2.png")
        #ico2 = QtGui.QIcon("")
        if self._cidPlotB:
            self.ui.mpl_widget.canvas.mpl_disconnect(self._cidPlotB)
            self.mplPickPointsB = False         
        if not self.mplPickPointsA:
            self._cidPlotA = self.ui.mpl_widget.canvas.mpl_connect('pick_event', self.OnPickA)
        else:
            self.ui.mpl_widget.canvas.draw()
        

    def SelectPointsB(self):
        if self._cidPlotA != None:
            self.ui.mpl_widget.canvas.mpl_disconnect(self._cidPlotA)
            self.mplPickPointsA = False
        if not self.mplPickPointsB:
            self._cidPlotB = self.ui.mpl_widget.canvas.mpl_connect('pick_event', self.OnPickB)
        else:
            self.ui.mpl_widget.canvas.draw()
        
    def OnPickA(self, event):
        """
        This is the pick_event handler for matplotlib
        This is the pick_event handler for matplotlib
        This method will get the coordinates of the mouse pointer and
        finds the closest point and retrieves the corresponding peptide sequence.
        Also draws a yellow circle around the point.--from Ashoka 5/29/08
        """
        if not isinstance(event.artist, Line2D): 
            return True
         
        line = event.artist
        xc = event.mouseevent.xdata
        yc = event.mouseevent.ydata
        xdata = line.get_xdata()
        ydata = line.get_ydata()
        maxd = 0.05
#        print 'xdata', type(xdata)
#        print 'xc', type(xc)
#        print 'ydata', type(ydata)
#        print 'yc', type(yc)
        if xc and yc:
            distances = N.hypot(xdata-xc, ydata-yc)
        else:
            distances = N.hypot(xdata, ydata)
        
        self.indexA = distances.argmin()
        self.selectHandleA.set_visible(True)
        self.selectHandleA.set_data([xdata[self.indexA]], [ydata[self.indexA]])
        self.cursorAInfo[0]=self.indexA
        self.cursorAInfo[1]=xdata[self.indexA]
        self.cursorAInfo[2]=ydata[self.indexA]
        self.cursorAInfo[3]=line.get_label()
        self.cursorStats()
        
        self.ui.mpl_widget.canvas.draw()
        print "Pick A"

    def OnPickB(self, event):
            if not isinstance(event.artist, Line2D): 
                return True
             
            line = event.artist
            xc = event.mouseevent.xdata
            yc = event.mouseevent.ydata
            xdata = line.get_xdata()
            ydata = line.get_ydata()
            maxd = 0.05
            if xc and yc:
                distances = N.hypot(xdata-xc, ydata-yc)
            else:
                distances = N.hypot(xdata, ydata)#event.mouseevent.xdata, ydata-event.mouseevent.ydata)
        
            self.indexB = distances.argmin()
            self.selectHandleB.set_visible(True)
            self.selectHandleB.set_data([xdata[self.indexB]], [ydata[self.indexB]])
            self.cursorBInfo[0]=self.indexB
            self.cursorBInfo[1]=xdata[self.indexB]
            self.cursorBInfo[2]=ydata[self.indexB]
            self.cursorBInfo[3]=line.get_label()
            self.cursorStats()
        
            self.ui.mpl_widget.canvas.draw()

            
    def focus_event(self):
        print "We're here"
    
    def __mplContext__(self, point):
        '''Create a menu for the mpl widget'''
        ct_menu = QMenu("Plot Menu", self.ui.mpl_widget)
        ct_menu.addAction(self.ui.actionZoom)
        ct_menu.addAction(self.ui.actionAutoScale)
        ct_menu.addSeparator()
        ct_menu.addAction(self.ui.actionPlotOptions)
        ct_menu.addSeparator()
        ct_menu.addAction(self.ui.actionClear)
        ct_menu.addSeparator()
        ct_menu.addAction(self.ui.handleActionA)
        ct_menu.addAction(self.ui.handleActionB)
        ct_menu.addAction(self.ui.cursorClear)
        ct_menu.addSeparator()
        ct_menu.addAction(self.ui.appendAction)
        ct_menu.addAction(self.ui.errorbarAction)
        ct_menu.addAction(self.ui.removeAction)
        ct_menu.addAction(self.ui.saveGraphAction)
        ct_menu.addSeparator()
        ct_menu.addAction(self.ui.hZoom)
        ct_menu.addAction(self.ui.testAction)
        ct_menu.exec_(self.ui.mpl_widget.mapToGlobal(point))
    
    def removeTrace(self):
        self.refreshPlotScripts()
        self.rd = Remove_Line_Dialog(self.plotDict, self.errorDict,  self)
        if self.rd.exec_():
            self.updatePlot()
            
    def fitData(self):
        print "Fit funcion here"
            
        
    def appendTrace(self):
        if self.varDict:
            import Plot_Setup_Dialog as PSD#need this so that things are not called too many times and cause a conflict
            localArrayList = []
            
            vars = self.varDict
            #print vars
            for key in vars.iterkeys():
                if type(vars.get(key)) is N.ndarray and len(N.shape(vars.get(key))) is 1:
                    localArrayList.append(key)
            localArrayList.sort()
            self.plot_setup = PSD.Define_Plot_Widget(localArrayList, vars, True,  self)
            self.plot_setup.show()
        else:
            print "No Parent Window"
    
    def appendErrorBars(self):
        if self.varDict:
            if len(self.lpcDict) >=1:
                import Error_Setup_Dialog as ESD
                parentArrayList = []
                vars = self.varDict
                for key in vars.iterkeys():
                    if type(vars.get(key)) is N.ndarray and len(N.shape(vars.get(key))) is 1:
                        parentArrayList.append(key)
                parentArrayList.sort()
                self.errorbar_setup = ESD.Define_Error_Plot(parentArrayList,  self.lpcDict, vars,  True,  self)
                self.errorbar_setup.show()
            else:
                print "There are no active plots"
    
    def plot_option_dialog(self):
        self.refreshPlotScripts()#this updates the plotDict to include lines added through the command line
        mpl = self.ui.mpl_widget.canvas
        self.od = Plot_Options_Dialog(self.plotDict, self.errorDict, self)
        self.od.plottitle_lineEdit.setText(mpl.PlotTitle)
        self.od.xlabel_lineEdit.setText(mpl.xtitle)
        self.od.ylabel_lineEdit.setText(mpl.ytitle)
        self.od.xmin_lineEdit.setText(str(mpl.ax.get_xlim()[0]))
        self.od.xmax_lineEdit.setText(str(mpl.ax.get_xlim()[1]))
        self.od.ymin_lineEdit.setText(str(mpl.ax.get_ylim()[0]))
        self.od.ymax_lineEdit.setText(str(mpl.ax.get_ylim()[1]))
        self.od.gridlines_cb.setChecked(self.grids)
        self.od.logx_cb.setChecked(self.logx)
        self.od.logy_cb.setChecked(self.logy)
        
                
        if self.od.exec_():
            self.xscale = (float(self.od.xmin_lineEdit.text()),float(self.od.xmax_lineEdit.text()))
            self.yscale = (float(self.od.ymin_lineEdit.text()),float(self.od.ymax_lineEdit.text()))
            self.logx = self.od.logx_cb.isChecked()
            self.logy = self.od.logy_cb.isChecked()
            self.grids = self.od.gridlines_cb.isChecked()
            self.plotTitle = self.od.plottitle_lineEdit.text()
            self.xtitle = self.od.xlabel_lineEdit.text()
            self.ytitle = self.od.ylabel_lineEdit.text()        
            self.updatePlot()

    def updatePlot(self):
        mpl = self.ui.mpl_widget.canvas
        mpl.PlotTitle = self.plotTitle
        mpl.xtitle = self.xtitle
        mpl.ytitle = self.ytitle
        mpl.ax.set_xlim(self.xscale)
        mpl.ax.set_ylim(self.yscale)
        mpl.ax.set_xscale(self.axis_scaling(self.logx))
        mpl.ax.set_yscale(self.axis_scaling(self.logy))
        mpl.ax.grid(self.grids)
        #self.refreshPlotScripts()
        mpl.format_labels()
        mpl.draw()
    
    def refreshPlotParams(self):
        if self.plotTitle != 'SubPlot':
            self.plotParams['plotTitle']=str(self.plotTitle)
        if self.grids == True:
            self.plotParams['grids'] = True
        if self.logx == True:
            self.plotParams['logx']=True
        if self.logy == True:
            self.plotParams['logy']=True
        self.plotParams['x_axlabel'] = str(self.xtitle)
        self.plotParams['y_axlabel'] = str(self.ytitle)
        self.plotParams['range_x']=self.xscale
        self.plotParams['range_y']=self.yscale

    def axis_scaling(self, bool):
        if bool is True:
            return 'log'
        else:
            return 'linear'
    
    def program_close(self):
        sys.exit()

    def zoom_plot(self):
        self.ui.mpl_widget.toolbar.zoom()
        
    def clear_plot(self):
        self.ui.mpl_widget.canvas.ax.cla()
        self.ui.mpl_widget.canvas.format_labels()
        self.ui.mpl_widget.canvas.draw()
        self.plotDict = {}
        self.lpcDict = {}
        self.errorDict ={}
        self.ui.tabWidget.setCurrentIndex(0)
    
    def __getlinecolor__(self):
        color = line_colors[self.line_num]
        if self.line_num is len(line_colors)-1:
            self.line_num = 0
        else:
            self.line_num+=1
        return color
    
    def initialize_plot(self, data2plot):#need to add logic to allow error bars to be added if they exist in the LPC
        if self.plotscript is None:
            self.plotscript = [probeLPC(data2plot)]#needs to be a list just in case there is more than one trace
        elif type(self.plotscript) == list:
            self.plotscript.append(probeLPC(data2plot))

        mplwidget = self.ui.mpl_widget.canvas
        if data2plot.ydict is None:#this is true when there is a singly x,y pair in a LPC
            self.plotDict[data2plot.ylabel]=(data2plot.data)
            self.lpcDict[data2plot.ylabel] = data2plot
            #data2plot.data.set_c(self.__getlinecolor__())
            if self.errorDict.has_key(data2plot.ylabel):
                errorlist = self.errorDict.pop(data2plot.ylabel)
                for sublist in errorlist:
                        for err in sublist:
                            err.remove()
            
            if data2plot.errorbars:#I DON"T LIKE THIS.  I'm WORRIED ABOUT MEMORY HOGGING!!!!!!!!!!!! Is there a better way to add errorbars
                if self.plotDict.has_key(data2plot.ylabel):
                    try:
                        data2plot.data.remove() 
                        self.plotDict.pop(data2plot.ylabel)
                        temp_color = data2plot.data.get_color()
                    except:
                        temp_color = data2plot.data.get_color()
                        print "No line to remove...moving on"
                else:
                    temp_color = self.__getlinecolor__()
                    
                eb = mplwidget.ax.errorbar(data2plot.data.get_xdata(),  data2plot.data.get_ydata(),  
                                      xerr = data2plot.get_xerr(),  yerr = data2plot.get_yerr(), 
                                      ls = data2plot.data.get_ls(),  lw = data2plot.data.get_lw(),
                                      marker = data2plot.data.get_marker(),  ms = data2plot.data.get_markersize(),  
                                      mfc = data2plot.data.get_mfc(),  picker = 5,  color = temp_color)#color = data2plot.data.get_color(), 
                data2plot.set_data(eb[0])#replaces data in order to minimize any memory problems.
                self.plotDict[data2plot.ylabel]=(eb[0])
                self.errorDict[data2plot.ylabel] = ([eb[1], eb[2]])#these two lists are contain the caps and bars.
            else:
                mplwidget.ax.add_line(data2plot.data)
                data2plot.data.set_c(self.__getlinecolor__())
                
        else:
            ydata_dict = data2plot.ydict
            for line in ydata_dict.itervalues():
                self.plotDict[line.ylabel]=(line.data)
                self.lpcDict[line.ylabel] = line
                #self.plotnames[line.ylabel] = [data2plot.xlabel,  line.ylabel]
                line.data.set_c(self.__getlinecolor__())
                mplwidget.ax.add_line(line.data)
        self.autoscale_plot()

            
    def dict_value(self, dictionary):
        return dictionary.values()[0]
    
    def dict_key(self, dictionary):
        return dictionary.keys()[0]
              
    def autoscale_plot(self):
        #self.rescale_plot()
        self.ui.mpl_widget.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True)
        self.ui.mpl_widget.canvas.draw()
        self.ui.tabWidget.setCurrentIndex(0)
            
    def rescale_plot(self):
        self.ui.mpl_widget.canvas.ax.relim()
        self.autoscale_plot() 
        
    def test_plot(self):
        self.generate_dummy_data()
        self.ui.tabWidget.setCurrentIndex(0)
    
    def generate_dummy_data(self):
        x = N.arange(0,10, N.random.random())
        y = N.cos(x-N.random.random())
        xdict = {'x':x}
        ydict = {'test':y}
        self.add_trace([xdict, ydict])

    def add_trace(self, dataDict):
        data2plot = LPC(dataDict)#LinePlotClass(dataDict)
        self.initialize_plot(data2plot)
    
    def getPlotScript(self):
        #print type(self.plotscript)
        if self.parent:
            self.parent.plotScripts[self.windowTitle] = ["lineplot(DATALIST = %s)" % self.plotscript]
            self.parent.__updatePlotScripts__()

    def lineplot(self, x = None,  y=None,     #I added this to the main GUI because I needed access to the localVars.getPubDict() in order to plot
                xlabel = 'x',             # a more elegant way would be nice, but this works for now.
                ylabel = 'y',
                xerr = None, 
                yerr = None, 
                color = None,
                mcolor = None, 
                linestyle = None,
                linewidth = None,
                marker = None,
                markersize = None,
                plotTitle = None,
                range_x = (None, None),
                range_y = (None, None),
                x_axlabel = None,
                y_axlabel = None,
                logx = False, 
                logy = False, 
                grids = False, 
                DATALIST = None):
                    
        from plotting.Plot_Widget_Line2D import Plot_Widget    
        if x != None or y != None:
            new_LPC = LPC()
            if x != None and y!=None:
                new_LPC.data = Line2D(x, y)
                new_LPC.data.set_picker(5)
            elif x!=None and y == None:
                calcx = N.arange(0,len(x))
                new_LPC.data = Line2D(calcx, x)
                new_LPC.data.set_picker(5)
            
            new_LPC.xlabel = xlabel
            new_LPC.ylabel = ylabel
            if type(range_x) is tuple:
                new_LPC.xscale = range_x
            elif type(range_x) is not tuple or None:
                print "range_x must be a tuple of min and max axis values"
            
            if type(range_y) is tuple:
                new_LPC.yscale = range_y
            elif type(range_y) is not tuple or None:
                print "range_y must be a tuple of min and max axis values"
                
            new_LPC.grids = grids
            new_LPC.plotTitle = plotTitle
            new_LPC.xtitle = x_axlabel
            new_LPC.ytitle = y_axlabel
            if markersize:
                new_LPC.data.set_markersize(markersize)
            if marker:
                new_LPC.data.set_marker(marker)
            if linewidth:
                new_LPC.data.set_linewidth(linewidth)
            if linestyle:
                new_LPC.data.set_linestyle(linestyle)
            if color:
                new_LPC.data.set_color(color)
            if mcolor:
                new_LPC.data.set_markerfacecolor(mcolor)
        
        plot = Plot_Widget(parent = self)
        try:
            if new_LPC:
                plot.initialize_plot(new_LPC)
        except:
            pass
        if DATALIST:
            varDict = self.localVars.getPubDict()
            #print varDict
            for line in DATALIST:
                #print "DataList Go"
                #print line
                #print makeLPC(line, varDict)
                plot.initialize_plot(makeLPC(line, varDict))
        plot.show()
        
if __name__ == "__main__":
    
    #from scipy import rand
    app = QApplication(sys.argv)
    a, b, c, d = S.rand(4, 15)
    x = N.arange(0,30, N.random.random())
    y = N.cos(x-N.random.random())
    y2 = N.sin(x-N.random.random())
    y3 = 2*N.sin(x-N.random.random())
    y4 = 2*N.cos(x-N.random.random())
    y5 = 3*N.sin(x-N.random.random())
    y6 = 4*N.cos(x-N.random.random())
    y7 = 5*N.sin(x-N.random.random())
    y8 = 6*N.cos(x-N.random.random())
    
    # make x data
    num = 100
    x = S.linspace(-10, 10, num=num)
    distancePerLag = x[1]-x[0]
    
    # make two gaussians, with different means
    offset = 2.0
    y1 = S.exp(-x**2/8.0)
    y2 = S.exp(-(x-offset)**2/1.0)

    dummyDict = {'None':None}
    #xdict = {'a':a}
    xdict = {'x':x}
    #xdict = {'None':None}
    #ydict = {'b':b,  'c':c}
    ydict = {'y1':y1,  'y2':y2}
    #ydict = {'y2':y2, 'y3':y3}
    #ydict = {'y2':y2, 'y3':y3, 'y4':y4, 'y5':y5, 'y6':y6,'y7':y7, 'y8':y8}
    totaldict = {'x':x,'y':y, 'y1':y1,'y2':y2, 'y3':y3, 'y4':y4, 'y5':y5, 'y6':y6,'y7':y7, 'y8':y8, 'c':c,  'd':d,  'a':a, 'b':b}
    data2plot = LPC([xdict,ydict])
    #data2plot.data.set_marker('o')
    #data2plot.set_yerr(c)
    
    #print type(data2plot.data)
    #lpcscript = getLPCScript(data2plot)
    #lpcscript = probeLPC(data2plot)
    #print lpcscript
    #constructLPC = makeLPC(lpcscript, totaldict)
    #print constructLPC
    
    #print "lineplot(DATALIST = %s)" % lpcscript

    
    #lineplot([x,y],marker = 'D',linestyle = '--', mcolor ='#ff0000', DATALIST = constructLPC)
    #lineplot(DATALIST = constructLPC)

    plot = Plot_Widget(data2plot,  varDict = totaldict)
    #plot = Plot_Widget(varDict = totaldict)
    #plot = Plot_Widget()
    plot.show()
    #print plot.plotscript
    sys.exit(app.exec_())     
